﻿using System.ComponentModel;
using System.Reflection;
using Dyao.Book.Contract;

namespace Dyao.Book.Application
{
    public static class TaskCenterCodeManager
    {
        private static bool _isLoaded;
        private static Type[] _actionKeysClassTypes;
        private static Dictionary<string, (MemberInfo, TaskCenterCodeDto)> _codeNameDict = new Dictionary<string, (MemberInfo, TaskCenterCodeDto)>(StringComparer.OrdinalIgnoreCase);
        static TaskCenterCodeManager()
        {
            _actionKeysClassTypes = new Type[]
            {
                typeof(TaskCenterCodes)
            };
        }

        /// <summary>
        /// 加载keys
        /// </summary>
        public static void LoadCodes()
        {
            if (_isLoaded) return;

            foreach (var t in _actionKeysClassTypes)
            {
                var fields = t.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

                foreach (var field in fields)
                {
                    var code = field.GetValue(null) as string;
                    if (string.IsNullOrWhiteSpace(code)) continue;

                    if (_codeNameDict.TryGetValue(code, out var tuple))
                    {
                        throw new ApplicationException($"任务中心Code({code})重复，{field.DeclaringType.FullName}.{field.Name}和{tuple.Item1.DeclaringType.FullName}.{tuple.Item1.Name}值相同");
                    }

                    var displayname = code;
                    var attr = (DescriptionAttribute)field.GetCustomAttribute(typeof(DescriptionAttribute));
                    if (attr != null && !string.IsNullOrWhiteSpace(attr.Description))
                    {
                        displayname = attr.Description;
                    }

                    _codeNameDict.Add(code, (field, new TaskCenterCodeDto(code, displayname)));
                }
            }

            _isLoaded = true;
        }

        /// <summary>
        /// 获取所有keys信息
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<TaskCenterCodeDto> GetAllCodes()
        {
            return _codeNameDict.Values.Select(a => a.Item2);
        }

        /// <summary>
        /// 是否存在key
        /// </summary>
        /// <param name="taskCode"></param>
        /// <returns></returns>
        public static bool IsExists(string taskCode)
        {
            return _codeNameDict.ContainsKey(taskCode);
        }

        /// <summary>
        /// 尝试获取key信息
        /// </summary>
        /// <param name="taskCode"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public static bool TryGet(string taskCode, out TaskCenterCodeDto model)
        {
            var isSucc = _codeNameDict.TryGetValue(taskCode, out var tuple);
            model = tuple.Item2;

            return isSucc;
        }
    }
}
